package main

import "fmt"

// 切片
func main() {
	var a []string
	var b = [5]int{55, 56, 57, 58}
	var c = []bool{false, true}
	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
	// 基于数组得到切片
	d := b[1:4]
	fmt.Println(d)
	fmt.Printf("%T\n", d)
	// 切片再次切片
	e := d[0 : len(d)-1]
	fmt.Println(e)
	// make函数构造切片
	f := make([]int, 5, 10)
	fmt.Println(f)
	// 通过len函数获取切片的长度
	fmt.Println(len(f))
	// 通过cap函数获取切片的容量
	fmt.Println(cap(f))

	// nil
	var g []int
	var h = []int{} // 声明并且初始化
	i := make([]int, 0)
	if g == nil {
		fmt.Println("g == nil")
	}
	if h == nil {
		fmt.Println("h == nil")
	}
	if i == nil {
		fmt.Println("i == nil")
	}
	fmt.Println(g, len(g), cap(g))
	fmt.Println(h, len(h), cap(h))
	fmt.Println(i, len(i), cap(i))

	// 切片的赋值拷贝
	// [100 0 0]
	// [100 0 0]
	j := make([]int, 3)
	k := j
	k[0] = 100
	fmt.Println(j)
	fmt.Println(k)

	// 切片的遍历
	l := []int{1, 2, 3, 4, 5}
	// 根据索引来遍历
	for i := 0; i < len(l); i++ {
		fmt.Println(i, l[i])
	}
	// for range 遍历
	for index, value := range l {
		fmt.Println(index, value)
	}

	// 切片的扩容
	// append()方法为切片添加元素
	// 切片要初始化之后才能使用
	var m []int // 此时它并没有申请内存
	m = append(m, 10)
	m[0] = 100
	fmt.Println(m)
	// 满足不了容量需求，扩容为原来的两倍(原来长度<1024，原来大于1024，则扩容为1.2倍)
	var n []int
	for i := 0; i < 10; i++ {
		n = append(n, i)
		fmt.Printf("%v len:%d cap:%d ptr:%p\n", n, len(n), cap(n), n)
	}
	// 可以一次添加多个元素
	n = append(n, 1, 2, 3, 4, 5)
	// 添加另一个切片中的元素 ...
	o := []int{10, 11, 12}
	n = append(n, o...)

	// copy()函数复制切片
	// copy是传值， :=是传引用
	p := []int{1, 2, 3, 4, 5}
	q := make([]int, 5, 5)
	r := q
	copy(q, p)
	q[0] = 100
	fmt.Println(p)
	fmt.Println(q)
	fmt.Println(r)

	// 切片删除元素
	s := []string{"上海", "广东", "深圳", "江苏"}
	s = append(s[0:2], s[3:]...)
	fmt.Println(s)
	// append(a[:index], a[index+1:]...)
}
